package com.biostime.qdingding.modules.qd.service;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.JAXBException;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.biostime.qdingding.common.config.Global;
import com.biostime.qdingding.modules.qd.api.dto.ContractDto;
import com.biostime.qdingding.modules.qd.entity.Pay;
import com.biostime.qdingding.modules.qd.entity.Transrecord;
import com.biostime.qdingding.modules.sys.entity.User;

/**
 * @author chenweicheng
 */
@Transactional
@Service
public class AlipayService {
	
	//AppID
    public static final String AppID = "2088121367803283";//2088021993962014
    
    //商户收款账号
    public static final String SELLER = "it@biostime.com.cn";//zhifubao@sharemarking.com
    
	@Autowired
	private PayService payService;
	
	@Autowired
	private TransrecordService  recordService;
	
	@Autowired
	private ContractService contractService;
				
	public static Logger logger=Logger.getLogger("api"); 
    
	 /**
     * 创建订单信息 
	 * @throws UnsupportedEncodingException  
     */
    public String getOrderInfo(HttpServletRequest request) throws UnsupportedEncodingException {
    	
    	AlipayService.logger.info("--------第一步：客户端获取支付宝支付信息--------"); 
    	
        //签约合作者身份ID
        String orderInfo = "partner=" + "\"" + AppID + "\"";
        
        //签约卖家支付宝账号
        orderInfo += "&seller_id=" + "\"" + SELLER + "\"";
        
		//生成商家订单号
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmsszzz");
		String tradeNo = String.valueOf(((int)(Math.random() * 9 + 1) * 1000))+sdf.format(new Date())+String.valueOf((int)
				((Math.random() * 9 + 1) * 10000));	
        
        //商家订单号
        orderInfo += "&out_trade_no=" + "\"" + tradeNo + "\"";
        
        //商品名称
        orderInfo += "&subject=" + "\"" + "支付合同余额" + "\"";
        
        //商品详情
        orderInfo += "&body=" + "\"" + "支付宝支付合同金额" + "\"";
        
        //商品金额
        orderInfo += "&total_fee=" + "\"" + request.getParameter("price") + "\"";
        
		//项目url
		String projectUrl = request.getRequestURI();
		String url[] = projectUrl.split("/");
		if(url.length>3){
			projectUrl = url[0]+"/"+url[1]+"/"+url[2];
		}
		String serverUrl = "http://"+Global.getConfig("domain")+"/qdingding-webapp"+Global.getConfig("adminPath")+
				"/qd/api/pay/alipayPayReturn";
        
        //服务器异步通知页面路径
        orderInfo += "&notify_url=" + "\"" + serverUrl + "\"";
        //服务接口名称， 固定值
        orderInfo += "&service=\"mobile.securitypay.pay\"";
        
        //支付类型， 固定值
        orderInfo += "&payment_type=\"1\"";
        
        //参数编码， 固定值        
        orderInfo += "&_input_charset=\"utf-8\"";
        
        //设置未付款交易的超时时间
        //默认30分钟，一旦超时，该笔交易就会自动被关闭。
        //取值范围：1m～15d。
        //m-分钟，h-小时，d-天，1c-当天（无论交易何时创建，都在0点关闭）。
        //该参数数值不接受小数点，如1.5h，可转换为90m。
        orderInfo += "&it_b_pay=\"30m\"";

        //extern_token为经过快登授权获取到的alipay_open_id,带上此参数用户将使用授权的账户进行支付
        //orderInfo += "&extern_token=" + "\"" + extern_token + "\"";
        //支付宝处理完请求后，当前页面跳转到商户指定页面的路径，可空
        orderInfo += "&return_url=\"m.alipay_icon.com\"";
        
        //调用银行卡支付，需配置此参数，参与签名， 固定值 （需要签约《无线银行卡快捷支付》才能使用）
        //orderInfo += "&paymethod=\"expressGateway\"";
    	
        // 对订单做RSA 签名
        String sign = AlipaySignService.sign(orderInfo,AlipaySignService.RSA_PRIVATE);
        
        try {
            // 仅需对sign 做URL编码
            sign = URLEncoder.encode(sign, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        
        // 完整的符合支付宝参数规范的订单信息
        orderInfo += "&sign=\"" + sign + "\"";
        
        orderInfo += "&sign_type=\"RSA\"";
        
        //插入支付记录表
        Pay payEntity = new Pay();
        payEntity.setMemberId(Integer.parseInt(request.getParameter("userId")));
        payEntity.setStudentId(Integer.parseInt(request.getParameter("studentId")));
        payEntity.setOutTradeNo(tradeNo); 
        payEntity.setCreateBy(new User("0")); 
        payEntity.setCreateDate(new Date());
        payEntity.setUpdateBy(new User("0"));
        payEntity.setUpdateDate(new Date());
        payEntity.setPlatform(1); 
        payEntity.setCenterId(Integer.parseInt(request.getParameter("centerId")));
        payService.save(payEntity); 
        
        AlipayService.logger.info("商家订单号："+tradeNo);
        AlipayService.logger.info("支付宝支付信息："+orderInfo); 
        
        return orderInfo;
    }
    
	/**
	 * 支付宝回调
	 * 插入收支记录
	 */	
	public void alipayPayReturn(String out_trade_no,String trade_no,String trade_status,double total_fee) throws JAXBException, UnsupportedEncodingException{
		
		AlipayService.logger.info("------------第二步：进入支付宝回调------------");
		AlipayService.logger.info("商家订单号："+out_trade_no);
        String userId = "0";
        String studentId = "0";
        Pay payEntity = payService.findByTradeNo(out_trade_no);
        if(trade_status.equals("TRADE_SUCCESS") && payEntity != null && recordService.apiGetByCode(out_trade_no) == null){
        	
            //确认支付	          
			userId = String.valueOf(payEntity.getMemberId());
        	studentId = String.valueOf(payEntity.getStudentId());
        	  
            //更新支付记录
            payEntity.setTransactionId(trade_no); 
            payService.updateTrasactionId(payEntity);
	    	int centerId = 0;
	    	int contractId = 0;
			List<ContractDto> listContract=contractService.apiGetContract(studentId);
			if(listContract != null && !listContract.isEmpty()){
				centerId = listContract.get(0).getCenterId();
				contractId = listContract.get(0).getId(); 
			}
			
			//插入收支记录
			Transrecord tr = new Transrecord();
			tr.setMoney(total_fee); // 交易金额
			tr.setDescription(String.format("支付宝支付", tr.getMoney())); //描述	
			tr.setPayCode(out_trade_no); //支付订单号
			tr.setCenterId(centerId);//早教中心
			tr.setContractId(contractId); //合同id
			tr.setMemberId(Integer.parseInt(userId)); //会员编号
			tr.setStudentId(Integer.parseInt(studentId)); //学员编号			
			tr.setType("0");
			tr.setPayType("2"); //支付方式（微信，支付宝，银联，现金）
			recordService.apiPay(tr); 
			
			//打印日志
			AlipayService.logger.info("-------------用户Id："+userId+", 学员Id："+studentId+"-----------"); 
			AlipayService.logger.info("支付宝支付成功"+"   "+"成交金额:"+total_fee+"元"+"   "+"商户订单号："+out_trade_no);	 			
			
        }else{
        	AlipayService.logger.info("未找到商家订单号："+out_trade_no);
        }
	}
	
	/**
	 * 
	 * 支付宝签名校验
	 * @param request
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public boolean checkSign(HttpServletRequest request){
		
		boolean flag = false;
		String orderInfo = null;
		SortedMap<Object,Object> map = new TreeMap<Object,Object>();   
	    Enumeration<String> paramNames = request.getParameterNames();  
	    while (paramNames.hasMoreElements()) {  
	      String paramName = (String) paramNames.nextElement();    
	      String[] paramValues = request.getParameterValues(paramName);  
	      if (paramValues.length == 1) {  
	        String paramValue = paramValues[0];  
	        if (paramValue.length() != 0 && (!paramName.equals("sign") || !paramName.equals("sign_type"))) {  
	          map.put(paramName, paramValue);  
	        }  
	      }  
	    }  
	    Set<Entry<Object, Object>> es = map.entrySet();
        Iterator<Entry<Object, Object>> it = es.iterator();  
        while(it.hasNext()) {  
            Map.Entry entry = (Map.Entry)it.next();  
            String k = (String)entry.getKey();  
            Object v = entry.getValue();  	
            orderInfo += "&"+k+"=" +v;
        } 
        
        //对订单做RSA签名
        String sign2 = AlipaySignService.sign(orderInfo,AlipaySignService.RSA_PRIVATE);
        try {
            //仅需对sign 做URL编码
            sign2 = URLEncoder.encode(sign2, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
                      
        if(sign2.equals(sign2)){
        	AlipayService.logger.info("-----------签名正确，该回调安全----------"); 
        	flag = true;
        }else{
        	AlipayService.logger.info("-----------签名错误，该回调失败----------"); 
       }
		
	   return flag;
	}
	
}
